home *** CD-ROM | disk | FTP | other *** search
/ PC Answers 1995 May / PC Answers CD-ROM 7 (Future Publishing) (May 1995).iso / vbits / code / appleman / eventmod.bas < prev    next >
Encoding:
BASIC Source File  |  1994-10-06  |  10.9 KB  |  368 lines

  1. ' Eventcod.bas
  2. '
  3. ' Sample program exploring how common algorithms can be
  4. ' converted to event driven versions for Visual Basic
  5. '
  6. ' Copyright (c) 1992, by Desaware
  7. '
  8. '
  9.  
  10. '   For demo purposes, we load our sample array with
  11. '   numbers 1 through ARRAYSIZE in random order
  12. '
  13. '   First call starts the initialization
  14. '   Returns 0 when initialization is complete, -1 otherwise
  15. '   Next call will start initialization again.
  16. '
  17. Function LoadSampleArray% ()
  18.     Static x%
  19.     Static inprogress%
  20.  
  21.     Dim temp, pos1%, pos2%, cnt%
  22.     
  23.     If Not inprogress% Then ' Do this part uninterrupted
  24.         inprogress% = -1
  25.         ' Initialize array values
  26.         For cnt% = 1 To ARRAYSIZE
  27.             SampleArray(cnt%) = cnt%
  28.         Next cnt%
  29.     End If
  30.  
  31.     ' Now shuffle them to random locations
  32.     
  33.     For cnt% = 1 To 100
  34.         pos1% = Int(Rnd * ARRAYSIZE + 1)
  35.         pos2% = Int(Rnd * ARRAYSIZE + 1)
  36.         temp = SampleArray(pos1%)
  37.         SampleArray(pos1%) = SampleArray(pos2%)
  38.         SampleArray(pos2%) = temp
  39.         x% = x% + 1
  40.         If x% > ARRAYSIZE Then
  41.             inprogress% = 0
  42.             Exit For
  43.         End If
  44.     Next cnt%
  45.     LoadSampleArray% = inprogress%
  46.  
  47.     
  48. End Function
  49.  
  50. '
  51. '
  52. ' -1 if a search the sort is in progress.  The calling
  53. ' program will generally keep calling this function until
  54. ' it receives a result = 0
  55. '
  56. ' On first call, startpos% and endpos% should be set to
  57. '   the start and end positions.
  58. '
  59. ' On all further calls, both of these parameters must
  60. '   be set to zero.
  61. '
  62. ' Calling this function with startpos% set to -1 aborts
  63. ' the current background operation and returns a result
  64. ' 1
  65. '
  66. Function QSortBackground% (ByVal startpos%, ByVal endpos%)
  67. Dim splitloc%
  68. Dim sp%, ep%    ' Internal use start & end position
  69. Static startlocs(300) As Integer
  70. Static endlocs(300) As Integer
  71. Static stackptr%
  72. ' When the function is cancelled, we clear the stack and
  73. ' flag the cancelation for return by the NEXT call -
  74. ' this makes it possible for the code that does the cancelation
  75. ' to not have to do the timer cleanup.
  76. Static cancelpending%
  77.  
  78.     
  79.     If startpos% = -1 Then
  80.         stackptr% = 0
  81.         cancelpending% = -1
  82.         QSortBackground% = -1
  83.         Exit Function
  84.         End If
  85.     
  86.     If endpos% > 0 Then ' It's the first call
  87.         stackptr% = 0   ' Reinitialize the stack pointer
  88.         ' Set up the stack for the next call
  89.         stackptr% = stackptr% + 1
  90.         startlocs(stackptr%) = startpos%
  91.         endlocs(stackptr%) = endpos%
  92.         QSortBackground% = -1
  93.         Exit Function
  94.         End If
  95.     
  96.     ' The sort is complete if the stack is empty
  97.     If stackptr% = 0 Then
  98.         If cancelpending% Then QSortBackground% = 1 Else QSortBackground% = 0
  99.         cancelpending% = 0
  100.         Exit Function
  101.         End If
  102.     
  103.     ' Get the current stack values and pop them off the stack
  104.     sp% = startlocs(stackptr%)
  105.     ep% = endlocs(stackptr%)
  106.     stackptr% = stackptr% - 1
  107.  
  108.     ' This entry is sorted if the start position is
  109.     ' beyond the end position
  110.     If sp% >= ep% Then
  111.         QSortBackground% = -1
  112.         Exit Function
  113.         End If
  114.  
  115.     ' Parition the array into two sections
  116.     splitloc% = QSplit%(sp%, ep%)
  117.  
  118.     ' Now quicksort each of the sections by pushing it
  119.     ' on the stack for the next call
  120.     
  121.     stackptr% = stackptr% + 1
  122.     startlocs(stackptr%) = splitloc% + 1
  123.     endlocs(stackptr%) = ep%
  124.  
  125.     stackptr% = stackptr% + 1
  126.     startlocs(stackptr%) = sp%
  127.     endlocs(stackptr%) = splitloc%
  128.  
  129.     QSortBackground% = -1   ' And continue
  130. End Function
  131.  
  132. '
  133. ' Simple quicksort algorithm without background processing
  134. '
  135. Sub QSortNoEvents (ByVal startpos%, ByVal endpos%)
  136. Dim splitloc%
  137.  
  138.     ' It's over if the start position is beyond the end
  139.     ' position
  140.     If startpos% >= endpos% Then Exit Sub
  141.  
  142.     ' Parition the array into two sections
  143.     splitloc% = QSplit%(startpos%, endpos%)
  144.     ' Now quicksort each of the sections
  145.     QSortNoEvents startpos%, splitloc%
  146.     QSortNoEvents splitloc% + 1, endpos%
  147.     ' That's all there is to it.
  148.  
  149. End Sub
  150.  
  151. '
  152. '   Given a portion of the SampleArray starting at startpos%
  153. '   and ending at endpos% (including both startpos% and
  154. '   endpos%), split the array at an arbitrary point.
  155. '   The selected point will be returned as a result by this
  156. '   function.
  157. '   All entries in the array subset from startpos% to this
  158. '   point are guaranteed to be smaller than the entry for this
  159. '   point.
  160. '   All entries in the array subset from this point to endpos%
  161. '   are guaranteed to be larger than the entry for this point.
  162. '
  163. Function QSplit% (ByVal startpos%, ByVal endpos%)
  164.  
  165. Dim splitloc%
  166. Dim partval#, tval#
  167. Dim fwdscan%, backscan%
  168.  
  169.     
  170.     ' If the array is nearly sorted, using the first entry
  171.     ' as the split value is likely to lead to a stack
  172.     ' overflow in VB, so we pick an entry near the center
  173.     ' as the split value, and move it out of the way to
  174.     ' the front of the array (see sidebar)
  175.  
  176.     If endpos% - startpos% > 5 Then
  177.         splitloc% = (endpos% - startpos%) / 2 + startpos%
  178.         tval# = SampleArray(splitloc%)
  179.         SampleArray(splitloc%) = SampleArray(startpos%)
  180.         SampleArray(startpos%) = tval#
  181.         End If
  182.  
  183.     ' We'll use the first value as the split value
  184.     partval# = SampleArray(startpos%)
  185.  
  186.     fwdscan% = startpos% + 1' Index to scan start to end
  187.     backscan% = endpos%     ' Index to scan end to start
  188.  
  189.     Do ' A left and right scan towards the partition value
  190.         ' Search forward until a value is found that is
  191.         ' larger than the partition value.
  192.         Do While fwdscan% <= endpos% And SampleArray(fwdscan%) < partval#
  193.             fwdscan% = fwdscan% + 1
  194.             Loop
  195.         ' Search backward until a value is found that is
  196.         ' smaller than the partition value.
  197.         Do While backscan% >= startpos% + 1 And SampleArray(backscan%) > partval#
  198.             backscan% = backscan% - 1
  199.             Loop
  200.         If fwdscan% < backscan% Then
  201.             ' These two entries are on the wrong side of
  202.             ' the partition value, so swap them
  203.             tval# = SampleArray(fwdscan%)
  204.             SampleArray(fwdscan%) = SampleArray(backscan%)
  205.             SampleArray(backscan%) = tval#
  206.         Else ' Otherwise, the partition is complete, i.e.
  207.             ' All entries from startpos% to backscan% are
  208.             ' smaller than partval#, all entries from
  209.             ' backscan%+1 to endpos% are larger than tval#
  210.             Exit Do
  211.         End If
  212.     Loop
  213.     ' The split is complete. The entry at position
  214.     ' backscan% is now the first entry smaller than
  215.     ' partval# when scaning from the end. We now swap it
  216.     ' with the partition value that was (as you recall)
  217.     ' the first entry in the array.
  218.     tval# = SampleArray(backscan%)
  219.     SampleArray(backscan%) = SampleArray(startpos%)
  220.     SampleArray(startpos%) = tval#
  221.  
  222.     ' And return the actual location of the partition value
  223.     QSplit% = backscan%
  224. End Function
  225.  
  226. ' Shows a search using a looping algorithm that is designed
  227. ' for use in an event driven environment.  The calling
  228. ' function will receive information indicating if the
  229. ' search is done or needs to be continued.  The search
  230. ' can be cancelled by simply ceasing the calls or
  231. ' reset by starting a new search
  232. '
  233. ' searchval& is the number to search for - it is only
  234. ' used when newsearch is true (-1)
  235. '
  236. ' newsearch% is -1 to start a new search, 0 to continue
  237. ' an existing search.
  238. '
  239. ' Returns the position of the number, or 0 if not found,
  240. ' -1 if a search the search is in progress.  The calling
  241. ' program will generally keep calling this function until
  242. ' it receives a result >= 0
  243. '
  244. '
  245. '
  246. Function SearchEventfully% (searchval, newsearch%)
  247. '
  248.     Static x%
  249.     Static savedsearchval
  250.     Dim cnt%
  251.  
  252.     If newsearch% Then  ' Setting up a new search
  253.         savedsearchval = searchval
  254.         x% = 1
  255.     End If
  256.  
  257.     If x% = 0 Then ' Search was not properly started
  258.         SearchEventfully% = x%
  259.         Exit Function
  260.     End If
  261.  
  262.  
  263.     ' Refer to the article for information on granularity
  264.     ' of background operations.
  265.     For cnt% = 1 To 100
  266.         ' Here we access the data.  In a real application
  267.         ' this could be a database or file access.
  268.         If savedsearchval = SampleArray(x%) Then
  269.             SearchEventfully% = x%
  270.             Exit Function
  271.         End If
  272.  
  273.         ' Increment x% and check for the end condition
  274.         x% = x% + 1
  275.         If x% > ARRAYSIZE Then Exit For
  276.     Next cnt%
  277.     
  278.     If x% > ARRAYSIZE Then
  279.         SearchEventfully% = 0
  280.         x% = 0
  281.     Else
  282.         SearchEventfully% = -1
  283.     End If
  284.     
  285. End Function
  286.  
  287. ' Shows a search using a looping algorithm that uses
  288. ' DoEvents to allow other applications to continue to
  289. ' run, and this application to continue to respond to
  290. ' events.
  291. '
  292. ' searchval is the number to search for
  293. '
  294. ' Returns the position of the number, or 0 if not found,
  295. ' -1 if a search is already in progress.
  296. '
  297. '
  298. Function SearchWithDoEvents% (searchval)
  299. '
  300.     Dim x%, counter%, temp%
  301.  
  302.     ' We use this flag to prevent multiple searches from
  303.     ' starting, which could lead to an overflow
  304.     Static NowSearching
  305.  
  306.     If NowSearching Then
  307.         ' A Search is already in progress - the calling
  308.         ' application should not start a new one due to the
  309.         ' risk of stack overflows.
  310.         SearchWithDoEvents% = -1
  311.         Exit Function
  312.     End If
  313.  
  314.     
  315.     For x% = 1 To ARRAYSIZE
  316.         ' Here we access the data.  In a real application
  317.         ' this could be a database or file access.
  318.         If searchval = SampleArray(x%) Then
  319.             SearchWithDoEvents% = x%
  320.             Exit Function
  321.         End If
  322.  
  323.         counter% = counter% + 1
  324.         If counter% = 10 Then ' Every 10th we do a DoEvents()
  325.             counter% = 0
  326.             temp% = DoEvents()  ' Let events take place
  327.             ' This would be a good place to monitor a
  328.             ' module or global variable for cancellation
  329.             ' of the search
  330.         End If
  331.         
  332.     Next x%
  333.  
  334.     ' No value found
  335.     SearchWithDoEvents% = 0
  336.     
  337.  
  338. End Function
  339.  
  340. ' Shows a search using a looping algorithm that ties up
  341. ' the system.
  342. '
  343. ' searchval% is the number to search for
  344. '
  345. ' Returns the position of the number, or 0 if not found
  346. '
  347. Function SearchWithoutEvents% (searchval)
  348.     Dim x%, oldmousepointer%
  349.  
  350.     oldmousepointer% = Screen.MousePointer
  351.     Screen.MousePointer = 11
  352.     For x% = 1 To ARRAYSIZE
  353.         ' Here we access the data.  In a real application
  354.         ' this could be a database or file access.
  355.         If searchval = SampleArray(x%) Then
  356.             SearchWithoutEvents% = x%
  357.             Screen.MousePointer = oldmousepointer%
  358.             Exit Function
  359.         End If
  360.     Next x%
  361.  
  362.     ' No value found
  363.     SearchWithoutEvents% = 0
  364.     Screen.MousePointer = oldmousepointer%
  365.  
  366. End Function
  367.  
  368.